package cn.bandeqing.dispatch.rpc.impl;

import cn.bandeqing.base.domain.AdminUserStore;
import cn.bandeqing.base.domain.CurrentAdminUser;
import cn.bandeqing.base.resp.Resp;
import cn.bandeqing.base.resp.Table;
import cn.bandeqing.dispatch.req.*;
import cn.bandeqing.dispatch.resp.*;
import cn.bandeqing.dispatch.rpc.IDispatchRpc;
import cn.bandeqing.frame.exception.CodeException;
import cn.bandeqing.order.entity.Order;
import cn.bandeqing.order.entity.OrderStatus;
import cn.bandeqing.order.resp.OrderDetailResp;
import cn.bandeqing.order.service.IOrderService;
import cn.bandeqing.orderWorker.entity.OrderWorker;
import cn.bandeqing.orderWorker.entity.OwStatus;
import cn.bandeqing.orderWorker.entity.OwType;
import cn.bandeqing.orderWorker.service.IOrderWorkerService;
import cn.bandeqing.product.entity.Product;
import cn.bandeqing.product.service.IProductService;
import cn.bandeqing.productInventoryRecord.entity.ChangeType;
import cn.bandeqing.productInventoryRecord.service.IProductInventoryRecordService;
import cn.bandeqing.productType.service.IProductTypeService;
import cn.bandeqing.stp.StpAdminUtil;
import cn.bandeqing.stp.StpWorkerUtil;
import cn.bandeqing.unipush2.entity.MsgType;
import cn.bandeqing.unipush2.service.IUnipush2Service;
import cn.bandeqing.user.entity.UsType;
import cn.bandeqing.workTime.entity.WorkTime;
import cn.bandeqing.workTime.service.IWorkTimeService;
import cn.bandeqing.worker.entity.Worker;
import cn.bandeqing.worker.entity.WorkerStatus;
import cn.bandeqing.worker.service.IWorkerService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import io.github.linpeilie.Converter;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.hutool.core.date.*;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static cn.bandeqing.order.entity.table.OrderTableDef.ORDER;
import static cn.bandeqing.orderWorker.entity.table.OrderWorkerTableDef.ORDER_WORKER;
import static cn.bandeqing.product.entity.table.ProductTableDef.PRODUCT;
import static cn.bandeqing.productInventoryRecord.entity.table.ProductInventoryRecordTableDef.PRODUCT_INVENTORY_RECORD;
import static cn.bandeqing.workTime.entity.table.WorkTimeTableDef.WORK_TIME;
import static cn.bandeqing.worker.entity.table.WorkerTableDef.WORKER;

@DubboService
public class DispatchRpcImpl implements IDispatchRpc {

    @Resource
    private IWorkTimeService workTimeService;
    @Resource
    private IOrderService orderService;
    @Resource
    private IOrderWorkerService orderWorkerService;
    @Resource
    private IWorkerService workerService;
    @Resource
    private IUnipush2Service unipush2Service;
    @Resource
    private IProductInventoryRecordService productInventoryRecordService;
    @Resource
    private IProductService productService;
    @Resource
    private Converter converter;

    @Override
    public Resp<Table<WorkTimeTable>> workTimeTable(WorkTimeTableReq req) {
        QueryWrapper qw = QueryWrapper.create()
                .where(WORK_TIME.WORKER_ID.eq(req.getWorkerId()))
                .where(WORK_TIME.WT_DATE.ge(req.getWtDateStart()))
                .where(WORK_TIME.WT_DATE.le(req.getWtDateStartEnd()))
                .where(WORK_TIME.MORNING.eq(req.getMorning()))
                .where(WORK_TIME.NOON.eq(req.getNoon()))
                .where(WORK_TIME.AFTERNOON.eq(req.getAfternoon()))
                .orderBy(WORK_TIME.WT_ID.desc());

        Page<WorkTimeTable> page = workTimeService.pageAs(Page.of(req.getCurrent(), req.getPageSize()), qw, WorkTimeTable.class);
        return Resp.success(Table.of(page.getRecords(), page.getTotalRow()));
    }

    @Override
    public void saveOrUpdate(WorkTimeSaveOrUpdateReq req) {
        WorkTime workTime = converter.convert(req, WorkTime.class);
        Assert.isTrue(workTimeService.saveOrUpdate(workTime), () -> new CodeException("workTimeService.saveOrUpdate(workTime)"));
    }

    @Override
    public Resp<Table<OrderDispatchTable>> table(OrderDispatchTableReq req) {
        QueryWrapper qw = QueryWrapper.create()
                .where(ORDER.ORDER_ID.eq(req.getOrderId()))
                .where(ORDER.SERVICE_TIME.ge(req.getServiceTimeStart()))
                .where(ORDER.SERVICE_TIME.le(req.getServiceTimeEnd()))
                .where(ORDER.CUSTOMER_NAME.eq(req.getCustomerName()))
                .where(ORDER.CUSTOMER_PHONE.eq(req.getCustomerPhone()))
                .where(ORDER.START_ADDRESS.eq(req.getStartAddress()))
                .where(ORDER.NEW_ADDRESS.eq(req.getNewAddress()))
                .where(ORDER.ORDER_STATUS.eq(req.getOrderStatus()))
                .where(ORDER.DISPATCH_STATUS.eq(req.getDispatchStatus()))
                .orderBy(ORDER.ORDER_ID.desc());

        if (req.getStoreId() == null) {
            CurrentAdminUser current = StpAdminUtil.getCurrent();
            if (current.checkStoreAccount()) {
                // 店铺账号 只能查询店铺下的权限
                qw.where(ORDER.STORE_ID.in(current.getStores().stream().map(AdminUserStore::getStoreId).toList()));
            }
        }

        Page<OrderDispatchTable> page = orderService.pageAs(Page.of(req.getCurrent(), req.getPageSize()), qw, OrderDispatchTable.class);
        return Resp.success(Table.of(page.getRecords(), page.getTotalRow()));
    }

    @Override
    public Resp<Table<HaveWorkerTable>> haveWorkertable(HaveWorkerTableReq req) {
        QueryWrapper qw = QueryWrapper.create()
                .select(WORKER.WORKER_ID.as(HaveWorkerTable::getWorkerId),
                        WORKER.WORKER_UUID.as(HaveWorkerTable::getWorkerUuid),
                        WORKER.WORKER_NICK_NAME.as(HaveWorkerTable::getWorkerNickName),
                        WORKER.WORKER_REAL_NAME.as(HaveWorkerTable::getWorkerRealName),
                        WORKER.WORKER_PHONE.as(HaveWorkerTable::getWorkerPhone),
                        WORKER.WORKER_TYPE.as(HaveWorkerTable::getWorkerType),
                        WORKER.WORKER_STATUS.as(HaveWorkerTable::getWorkerStatus),
                        WORKER.WORKER_NATION.as(HaveWorkerTable::getWorkerNation),
                        WORKER.WORKER_SEX.as(HaveWorkerTable::getWorkerSex),
                        WORKER.WORKER_AGE.as(HaveWorkerTable::getWorkerAge),
                        WORKER.WORKER_ADDRESS.as(HaveWorkerTable::getWorkerAddress),
                        WORKER.WORKER_YEAR.as(HaveWorkerTable::getWorkerYear),
                        WORKER.WORKER_SKILLS.as(HaveWorkerTable::getWorkerSkills),
                        WORKER.WORKER_TOOLS.as(HaveWorkerTable::getWorkerTools),
                        WORKER.WORKER_LEVEL.as(HaveWorkerTable::getWorkerLevel),
                        ORDER_WORKER.OW_ID.as(HaveWorkerTable::getOwId),
                        ORDER_WORKER.OW_TYPE.as(HaveWorkerTable::getOwType),
                        ORDER_WORKER.OW_STATUS.as(HaveWorkerTable::getOwStatus),
                        ORDER_WORKER.CREATE_TIME.as(HaveWorkerTable::getCreateTime),
                        ORDER_WORKER.CREATE_USER_NAME.as(HaveWorkerTable::getCreateUserName),
                        ORDER_WORKER.CREATE_USER_ID.as(HaveWorkerTable::getCreateUserId),
                        ORDER_WORKER.UPDATE_TIME.as(HaveWorkerTable::getUpdateTime),
                        ORDER_WORKER.UPDATE_USER_NAME.as(HaveWorkerTable::getUpdateUserName),
                        ORDER_WORKER.UPDATE_USER_ID.as(HaveWorkerTable::getUpdateUserId))
                .innerJoin(WORKER).on(WORKER.WORKER_ID.eq(ORDER_WORKER.WORKER_ID))
                .where(ORDER_WORKER.ORDER_ID.eq(req.getOrderId()))
                .orderBy(ORDER_WORKER.OW_TYPE.desc());
        Page<HaveWorkerTable> page = orderWorkerService.pageAs(Page.of(req.getCurrent(), req.getPageSize()), qw, HaveWorkerTable.class);
        return Resp.success(Table.of(page.getRecords(), page.getTotalRow()));
    }

    @Override
    public Resp<Table<DispatchWorkerTable>> dispatchWorkertable(DispatchWorkerTableReq req) {
        QueryWrapper qw = QueryWrapper.create()
                .select(WORKER.WORKER_ID.as(DispatchWorkerTable::getWorkerId),
                        WORKER.WORKER_UUID.as(DispatchWorkerTable::getWorkerUuid),
                        WORKER.WORKER_NICK_NAME.as(DispatchWorkerTable::getWorkerNickName),
                        WORKER.WORKER_REAL_NAME.as(DispatchWorkerTable::getWorkerRealName),
                        WORKER.WORKER_PHONE.as(DispatchWorkerTable::getWorkerPhone),
                        WORKER.WORKER_TYPE.as(DispatchWorkerTable::getWorkerType),
                        WORKER.WORKER_STATUS.as(DispatchWorkerTable::getWorkerStatus),
                        WORKER.WORKER_NATION.as(DispatchWorkerTable::getWorkerNation),
                        WORKER.WORKER_SEX.as(DispatchWorkerTable::getWorkerSex),
                        WORKER.WORKER_AGE.as(DispatchWorkerTable::getWorkerAge),
                        WORKER.WORKER_ADDRESS.as(DispatchWorkerTable::getWorkerAddress),
                        WORKER.WORKER_YEAR.as(DispatchWorkerTable::getWorkerYear),
                        WORKER.WORKER_CITY.as(DispatchWorkerTable::getWorkerCity),
                        WORKER.WORKER_SKILLS.as(DispatchWorkerTable::getWorkerSkills),
                        WORKER.WORKER_TOOLS.as(DispatchWorkerTable::getWorkerTools),
                        WORKER.WORKER_LEVEL.as(DispatchWorkerTable::getWorkerLevel),
                        WORKER.STORE_ID.as(DispatchWorkerTable::getStoreId),
                        WORKER.STORE_NAME.as(DispatchWorkerTable::getStoreName))
//                .leftJoin(ORDER_WORKER).on(ORDER_WORKER.WORKER_ID.eq(WORKER.WORKER_ID))
//                .where(ORDER_WORKER.ORDER_ID.ne(req.getOrderId()).or(ORDER_WORKER.ORDER_ID.isNull()))
//                .where(ORDER_WORKER.ORDER_ID.isNull())
                .where(WORKER.WORKER_ID.notIn(req.getWorkerIds()))
                .where(WORKER.WORKER_ID.eq(req.getWorkerId()))
                .where(WORKER.WORKER_UUID.eq(req.getWorkerUuid()))
                .where(WORKER.WORKER_NICK_NAME.eq(req.getWorkerNickName()))
                .where(WORKER.WORKER_REAL_NAME.eq(req.getWorkerRealName()))
                .where(WORKER.WORKER_PHONE.eq(req.getWorkerPhone()))
                .where(WORKER.WORKER_TYPE.eq(req.getWorkerType()))
                .where(WORKER.WORKER_STATUS.eq(req.getWorkerStatus()))
                .where(WORKER.WORKER_NATION.eq(req.getWorkerNation()))
                .where(WORKER.WORKER_SEX.eq(req.getWorkerSex()))
                .where(WORKER.WORKER_ADDRESS.eq(req.getWorkerAddress()))
                .where(WORKER.WORKER_CITY.eq(req.getWorkerCity()))
                .where(WORKER.WORKER_SKILLS.eq(req.getWorkerSkills()))
                .where(WORKER.WORKER_TOOLS.eq(req.getWorkerTools()))
                .where(WORKER.WORKER_LEVEL.eq(req.getWorkerLevel()))
                .where(WORKER.STORE_ID.eq(req.getStoreId()));

        CurrentAdminUser current = StpAdminUtil.getCurrent();
        if (current.getUsType().equals(UsType.company.getValue())) {
            // 非公司账号
            List<Long> storeIds = current.getStores().stream().map(AdminUserStore::getStoreId).toList();
            qw.where(WORKER.STORE_ID.in(storeIds));
        }


        if (req.getWorkTime() != null && req.getWorkTime() == 1) {
            Order order = orderService.getOne(QueryWrapper.create()
                    .select(ORDER.SERVICE_TIME)
                    .where(ORDER.ORDER_ID.eq(req.getOrderId())));

            if (ObjUtil.isNull(order) || ObjUtil.isNull(order.getServiceTime())) {
                return Resp.error("订单未设置服务时间 请设置后重试");
            }

            DateTime serviceTime = DateTime.of(order.getServiceTime());
            int hourOfDay = serviceTime.getField(DateField.HOUR_OF_DAY);
            qw.innerJoin(WORK_TIME).on(WORK_TIME.WORKER_ID.eq(WORKER.WORKER_ID));
            qw.where(WORK_TIME.WT_DATE.eq(DateUtil.format(order.getServiceTime(), DatePattern.NORM_DATE_FORMAT)));
            // 日程开启
            if (hourOfDay >= 8 && hourOfDay < 12) {
                qw.where(WORK_TIME.MORNING.eq(true));
            } else if (hourOfDay >= 12 && hourOfDay < 18) {
                qw.where(WORK_TIME.NOON.eq(true));
            } else {
                qw.where(WORK_TIME.AFTERNOON.eq(true));
            }
        }

        Page<DispatchWorkerTable> page = workerService.pageAs(Page.of(req.getCurrent(), req.getPageSize()), qw, DispatchWorkerTable.class);
        return Resp.success(Table.of(page.getRecords(), page.getTotalRow()));
    }

    @Override
    @Transactional
    public Resp<Void> plan(DispatchPlanReq req) {
        OrderWorker ow = converter.convert(req, OrderWorker.class);
        ow.setOwStatus(OwStatus.wait);
        boolean save = orderWorkerService.saveOrUpdate(ow);
        Assert.isTrue(save, CodeException::new);

        Worker worker = workerService.getOne(QueryWrapper.create()
                .select(WORKER.WORKER_ID, WORKER.WORKER_NICK_NAME, WORKER.WORKER_CID)
                .where(WORKER.WORKER_ID.eq(ow.getWorkerId())));

        if (ObjUtil.isNotNull(worker) && StrUtil.isNotBlank(worker.getWorkerCid())) {
            unipush2Service.sendDispatchMsg(ow.getWorkerId(), ow.getOrderId(), ow.getOwId(), MsgType.dispatch, worker);
        }

        return Resp.success();
    }

    @Override
    public Resp<Void> modify(DispatchModifyReq req) {
        OrderWorker ow = converter.convert(req, OrderWorker.class);
        boolean b = orderWorkerService.updateById(ow);
        Assert.isTrue(b, CodeException::new);
        return Resp.success();
    }

    @Override
    public Resp<Void> modifyDispatchStatus(MofifyDispatchStatusReq req) {
        Order order = converter.convert(req, Order.class);
        boolean b = orderService.updateById(order);
        Assert.isTrue(b, CodeException::new);
        return Resp.success();
    }

    @Override
    public Resp<Void> modifyWorkTimeSwitch(ModifyWorkTimeSwitchReq req) {
        WorkTime wt = converter.convert(req, WorkTime.class);
        boolean b = workTimeService.updateById(wt);
        Assert.isTrue(b, CodeException::new);
        return Resp.success();
    }

    @Override
    public Resp<List<DispatchListResp>> list(DispatchListReq req) {
        Long workerId = StpWorkerUtil.getLoginId();
        QueryWrapper qw = QueryWrapper.create()
                .select(ORDER.START_ADDRESS.as(DispatchListResp::getStartAddress),
                        ORDER.DISTANCE.as(DispatchListResp::getDistance),
                        ORDER.SERVICE_TIME.as(DispatchListResp::getServiceTime),
                        ORDER.NEW_ADDRESS.as(DispatchListResp::getNewAddress),
                        ORDER.ORDER_STATUS.as(DispatchListResp::getOrderStatus),
                        ORDER.ORDER_ID.as(DispatchListResp::getOrderId),
                        PRODUCT.PRODUCT_NAME.as(DispatchListResp::getProductName),
                        PRODUCT.PRODUCT_TYPE_NAME.as(DispatchListResp::getProductTypeName),
                        PRODUCT.MOVE_HOUSE.as(DispatchListResp::getMoveHouse),
                        ORDER_WORKER.OW_ID.as(DispatchListResp::getOwId),
                        ORDER_WORKER.OW_TYPE.as(DispatchListResp::getOwType))
                .innerJoin(ORDER).on(ORDER.ORDER_ID.eq(ORDER_WORKER.ORDER_ID))
                .leftJoin(PRODUCT).on(ORDER.PRODUCT_ID.eq(PRODUCT.PRODUCT_ID))
                .where(ORDER_WORKER.WORKER_ID.eq(workerId))
                .orderBy(ORDER.SERVICE_TIME.desc())
                .limit((req.getPage() - 1) * req.getSize(), req.getSize());
        if (req.getType() == 0) {
            // 待接单
            qw.where(ORDER_WORKER.OW_STATUS.eq(OwStatus.wait))
                    .where(ORDER.ORDER_STATUS.eq(OrderStatus.confirm));
        } else if (req.getType() == 1) {
            // 进行中
            qw.where(ORDER_WORKER.OW_STATUS.in(OwStatus.erp_accept, OwStatus.worker_accept))
                    .where(ORDER.ORDER_STATUS.eq(OrderStatus.confirm));
        } else if (req.getType() == 2) {
            // 已完成
            qw.where(ORDER_WORKER.OW_STATUS.in(OwStatus.erp_accept, OwStatus.worker_accept))
                    .where(ORDER.ORDER_STATUS.eq(OrderStatus.complete));
        }
        List<DispatchListResp> dispatchListResps = orderWorkerService.listAs(qw, DispatchListResp.class);
        return Resp.success(dispatchListResps);
    }

    @Override
    @Transactional
    public synchronized Resp<Void> handle(DispatchHandleReq req) {
        OrderWorker dbOw = orderWorkerService.getOne(QueryWrapper.create()
                .select(ORDER_WORKER.OW_STATUS, ORDER_WORKER.OW_TYPE)
                .where(ORDER_WORKER.OW_ID.eq(req.getOwId())));
        Assert.isTrue(OwStatus.wait.equals(dbOw.getOwStatus()), CodeException::new);

        OrderWorker ow = converter.convert(req, OrderWorker.class);

        if (OwStatus.worker_accept.equals(ow.getOwStatus())) {
            // 接受 除了领队只能有一个其他都不设限制
            if (OwType.captain.equals(dbOw.getOwType())) {
                // 领队需要排除其他领队
                long count = orderWorkerService.count(QueryWrapper.create()
                        .where(ORDER_WORKER.OW_TYPE.eq(OwType.captain))
                        .where(ORDER_WORKER.OW_STATUS.in(OwStatus.worker_accept, OwStatus.erp_accept))
                        .where(ORDER_WORKER.ORDER_ID.eq(req.getOrderId())));
                if (count > 0) {
                    // 已经有人接单了需要把自己排除
                    ow.setOwStatus(OwStatus.worker_accept_other_confirm);
                } else {
                    // 自己可以接 但是需要把其他没接的排除
                    List<Long> longs = orderWorkerService.listAs(QueryWrapper.create()
                            .select(ORDER_WORKER.OW_ID)
                            .where(ORDER_WORKER.OW_TYPE.eq(OwType.captain))
                            .where(ORDER_WORKER.OW_STATUS.eq(OwStatus.wait))
                            .where(ORDER_WORKER.ORDER_ID.eq(req.getOrderId())), Long.class);
                    if (!longs.isEmpty()) {
                        // 需要排除多余队长
                        orderWorkerService.update(OrderWorker.builder()
                                .owStatus(OwStatus.worker_other_confirm)
                                .build(), QueryWrapper.create()
                                .where(ORDER_WORKER.OW_ID.in(longs)));
                    }
                }
            }
        } else if (OwStatus.worker_refuse.equals(ow.getOwStatus())) {
            // 拒绝
            System.out.println();
        }

        boolean b = orderWorkerService.updateById(ow);
        Assert.isTrue(b, CodeException::new);
        return Resp.success();
    }

    @Override
    public Resp<DispatchDetailResp> detail(DispatchDetailReq req) {
        OrderWorker ow = orderWorkerService.getOne(QueryWrapper.create()
                .select(ORDER_WORKER.OW_ID, ORDER_WORKER.OW_TYPE, ORDER_WORKER.OW_STATUS)
                .where(ORDER_WORKER.OW_ID.eq(req.getOwId())));

        // 待接单 & 订单待接单 || 已接单 才能进来查看订单详情
        Assert.isTrue((req.getType() == 0 && OwStatus.wait.equals(ow.getOwStatus())) || OwStatus.worker_accept.equals(ow.getOwStatus()) || OwStatus.erp_accept.equals(ow.getOwStatus())
                , () -> new CodeException("状态异常，请稍后再试"));

        DispatchDetailResp resp = orderService.getOneAs(QueryWrapper.create()
                .select(ORDER.ORDER_ID.as(DispatchDetailResp::getOrderId),
                        ORDER.CUSTOMER_NAME.as(DispatchDetailResp::getCustomerName),
                        ORDER.CUSTOMER_PHONE.as(DispatchDetailResp::getCustomerPhone),
                        ORDER.SERVICE_TIME.as(DispatchDetailResp::getServiceTime),
                        ORDER.DISTANCE.as(DispatchDetailResp::getDistance),
                        ORDER.START_ADDRESS.as(DispatchDetailResp::getStartAddress),
                        ORDER.START_ADDRESS_LAT.as(DispatchDetailResp::getStartAddressLat),
                        ORDER.START_ADDRESS_LNG.as(DispatchDetailResp::getStartAddressLng),
                        ORDER.NEW_ADDRESS.as(DispatchDetailResp::getNewAddress),
                        ORDER.NEW_ADDRESS_LAT.as(DispatchDetailResp::getNewAddressLat),
                        ORDER.NEW_ADDRESS_LNG.as(DispatchDetailResp::getNewAddressLng),
                        ORDER.PRODUCT_ID.as(DispatchDetailResp::getProductId),
                        ORDER.PRODUCT_NAME.as(DispatchDetailResp::getProductName),
                        ORDER.CITY_CODE.as(DispatchDetailResp::getCityCode),
                        ORDER.CITY_NAME.as(DispatchDetailResp::getCityName),
                        ORDER.START_FLOOR.as(DispatchDetailResp::getStartFloor),
                        ORDER.START_ELEVATOR.as(DispatchDetailResp::getStartElevator),
                        ORDER.NEW_FLOOR.as(DispatchDetailResp::getNewFloor),
                        ORDER.NEW_ELEVATOR.as(DispatchDetailResp::getNewElevator),
                        ORDER.SERVICE_REMARK.as(DispatchDetailResp::getServiceRemark))
                .where(ORDER.ORDER_ID.eq(req.getOrderId())), DispatchDetailResp.class);

        Product p = productService.getById(resp.getProductId());
//        resp.setProductTypeId(p.getProductTypeId());
        resp.setProductName(p.getProductName());
        resp.setProductTypeName(p.getProductTypeName());
        resp.setMoveHouse(p.getMoveHouse());

        resp.setOwId(ow.getOwId());
        resp.setOwType(ow.getOwType().getValue());

        if (req.getType() == 0 || req.getType() == 2 || resp.getOwType() != 3) {
            // 待接单和已完成不显示客户信息 并且要是领队
            resp.setCustomerName("");
            resp.setCustomerPhone("");
        }

        List<OrderDetailResp.ProductDetail> productDetails = productInventoryRecordService.listAs(QueryWrapper.create()
                .where(PRODUCT_INVENTORY_RECORD.ORDER_ID.eq(req.getOrderId()))
                .where(PRODUCT_INVENTORY_RECORD.CHANGE_TYPE.in(ChangeType.order_save)), OrderDetailResp.ProductDetail.class);

        resp.setProductDetails(productDetails);

        if (req.getType() == 1 || req.getType() == 2) {
            // 进行中和已完成查询队伍成员
            QueryWrapper qw = QueryWrapper.create()
                    .select(ORDER_WORKER.OW_TYPE.as(DispatchDetailResp.TeamMember::getOwType),
                            WORKER.WORKER_NICK_NAME.as(DispatchDetailResp.TeamMember::getWorkerNickName),
                            WORKER.WORKER_PHONE.as(DispatchDetailResp.TeamMember::getWorkerPhone),
                            WORKER.WORKER_TOOLS.as(DispatchDetailResp.TeamMember::getWorkerTools),
                            WORKER.WORKER_SKILLS.as(DispatchDetailResp.TeamMember::getWorkerSkills))
                    .innerJoin(WORKER).on(WORKER.WORKER_ID.eq(ORDER_WORKER.WORKER_ID))
                    .where(ORDER_WORKER.ORDER_ID.eq(req.getOrderId()))
                    .where(ORDER_WORKER.OW_STATUS.in(OwStatus.erp_accept, OwStatus.worker_accept));

            if (OwType.captain.equals(ow.getOwType())) {
                // 自己是队长 查询所有组员
                qw.where(ORDER_WORKER.OW_TYPE.ne(OwType.captain));
            } else {
                // 查询队长
                qw.where(ORDER_WORKER.OW_TYPE.eq(OwType.captain));
            }

            // 查询队员或组长
            List<DispatchDetailResp.TeamMember> teamMembers = orderWorkerService.listAs(qw, DispatchDetailResp.TeamMember.class);
            resp.setTeamMembers(teamMembers);
        }

        return Resp.success(resp);
    }

    @Override
    public Resp<Void> forcePlan(DispatchForcePlanReq req) {
        Worker worker = workerService.getOne(WORKER.WORKER_PHONE.eq(req.getWorkerPhone()));

        Assert.notNull(worker, () -> new CodeException("对应手机号服务人员不存在，请检查手机号输入是否正确"));
        Assert.isTrue(WorkerStatus.pass.equals(worker.getWorkerStatus()), () -> new CodeException("小哥状态异常"));

        OrderWorker ow = converter.convert(req, OrderWorker.class);

        if (OwType.captain.equals(ow.getOwType())) {
            // 领队只能有一个
            long count = orderWorkerService.count(QueryWrapper.create()
                    .where(ORDER_WORKER.ORDER_ID.eq(req.getOrderId()))
                    .where(ORDER_WORKER.OW_TYPE.eq(OwType.captain))
                    .where(ORDER_WORKER.OW_STATUS.in(OwStatus.erp_accept, OwStatus.worker_accept)));
            Assert.isTrue(count == 0, () -> new CodeException("此订单已有确认接单的领队"));
        }

        ow.setOwStatus(OwStatus.erp_accept);
        ow.setWorkerId(worker.getWorkerId());

        Assert.isTrue(orderWorkerService.save(ow), CodeException::new);

        return Resp.success();
    }

}
